
import java.io.Serializable;
import java.util.ArrayList;
import org.jgap.RandomGenerator;
import org.jgap.gp.IGPFitnessEvaluator;
import org.jgap.gp.IGPProgram;
import org.jgap.gp.INaturalGPSelector;
import org.jgap.gp.impl.GPGenotype;
import org.jgap.gp.impl.GPPopulation;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Heitor
 */
public class TruncationSelector
        implements INaturalGPSelector, Serializable, Cloneable {

    private double m_threshold;

    public TruncationSelector(double m_thereshold) {
        setThreshold(m_thereshold);
    }

    public void setThreshold(double m_thereshold) {
        if (m_thereshold > 1) {
            this.m_threshold = 1;
        }
        if (m_thereshold < 0) {
            this.m_threshold = 0;
        }
        this.m_threshold = m_thereshold;
    }

    @Override
    public IGPProgram select(GPGenotype a_genotype) {
        GPPopulation pop = a_genotype.getGPPopulation();
        IGPProgram bestProgram = null;
        int index = 0;
        RandomGenerator random = 
                a_genotype.getGPConfiguration().getRandomGenerator();
        int popSize = pop.getPopSize();
        int numBeasts = (int) (popSize * m_threshold);
        IGPProgram[] bests = new IGPProgram[numBeasts];
        ArrayList<IGPProgram> progs = new ArrayList<IGPProgram>(popSize);
        for (int i = 0; i < pop.getGPPrograms().length; i++) {
            progs.add((pop.getGPPrograms())[i]);

        }
        for (int i = 0; i < numBeasts; i++) {
            bests[i] = getBestOfArray(progs);
        }
        bestProgram = bests[random.nextInt(numBeasts)];
        System.out.println("Seleção Truncamento");
        System.out.println("Indivíduo se: " + 
                bestProgram.getChromosome(0).toStringNorm(0));
        System.out.println("Fitness:" + bestProgram.getFitnessValue());
        System.out.println("Profundidade:" + 
                bestProgram.getChromosome(0).getSize(0));
        System.out.println("");
        return bestProgram;
    }

    @Override
    public Object clone() {
        TruncationSelector ts = new TruncationSelector(m_threshold);
        return ts;
    }

    private IGPProgram getBestOfArray(ArrayList<IGPProgram> progs) {
        double best = Double.MAX_VALUE;
        IGPProgram bestOfPop = null;
        int indexofBest = 0;
        for (int i = 0; i < progs.size(); i++) {
            IGPProgram iGPProgram = progs.get(i);

            if (iGPProgram.getFitnessValue() < best) {
                best = iGPProgram.getFitnessValue();
                bestOfPop = iGPProgram;
                indexofBest = i;
            }
        }
        progs.remove(bestOfPop);


        return bestOfPop;
    }
}
